package com.dfec.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.dfec.cache.redis.Cache;
import com.dfec.cache.redis.Redis;
import com.dfec.model.Msg;
import com.dfec.utils.Consists;
import com.dfec.utils.PropertiesUtil;
import com.dfec.utils.ResponseUtil;
import com.dfec.utils.Sign;
import com.dfec.utils.StringUtils;
import com.sx.service.UserLoginService;

/**
 * Servlet Filter implementation class SignFilter
 */
@WebFilter(description = "签名验证", urlPatterns = { "/*" },
initParams={@WebInitParam(name ="chain_do" , value = "us;bjimg;uploadfiles;login;register;upload;WangEditorImgUpload")})
public class SignFilter implements Filter {
	private List<Object> list=null;
    Msg msg=null;
    private String chain_do_str;       
	private String[] chain_do_arr;
    /**
     * Default constructor. 
     */
    public SignFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
		   this.chain_do_str = null; 
	       this.chain_do_arr = null; 
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		list=new ArrayList<>();
		msg=new Msg();
		
		  String url=((HttpServletRequest)request).getServletPath();
		  boolean needFilter = true;  
		  String[] par = url.split("/");
	        for (String page : chain_do_arr) {// 遍历例外url数组   
	            // 判断当前URL是否与例外页面相同 
	            if(par[1].equals(page)){ // 从第2个字符开始取（把前面的/去掉） 
	                needFilter = false;     
	                continue;     
	            }     
	        }   
	        if (!needFilter) {//在过滤url之外     
	            chain.doFilter(request, response); 
	            return;
	        } else {// 不在过滤url之外
	        	 String time = request.getParameter("time");
	             String token = request.getParameter("token");
	             String sign = request.getParameter("sign");
	                 //验证必备参数是否有效
	     	        if(StringUtils.isBlank(time)||
	     	           StringUtils.isBlank(token)||
	     	           StringUtils.isBlank(sign)) {
	     	        	msg.setCode(Consists.DATA_Code_OK__NODATA);
	     	        	msg.setMsg(Consists.Error_Msg_PAR_FAIL);
	     	        	 System.err.println("参数不全");
	     	        	list.add(msg);
	     	        	ResponseUtil.sendScript((HttpServletResponse)response, JSON.toJSONString(list));
	     	        	return;
	     	        }else 	if(StringUtils.isNotBlank(time)&&
	     	 	           StringUtils.isNotBlank(token)&&
	     	 	           StringUtils.isNotBlank(sign)) {
	             		 long longtime=Long.parseLong(time);
	             		 int result =(int) (System.currentTimeMillis()-longtime)/1000;
	             		 //请求时间超过10秒视为非法请求
	             		 if(result>60) {
	             			    msg.setCode(Consists.DATA_Code_OK__NODATA);
	             	        	msg.setMsg(Consists.DATA_Msg_REQUEST_TIMEOUT);
	             	        	list.add(msg);
	             	       	    System.err.println("过期"+result+"+"+System.currentTimeMillis());
	             	        	ResponseUtil.sendScript((HttpServletResponse)response, JSON.toJSONString(list));
	             	        	return;
	             		 }
	             		//查看缓存验证token对应账号是否存在
	                   	Cache cache = Redis.use();
	                   	boolean cachetokenExist = cache.exists(token);
	                   
	                   	if(!cachetokenExist) {
	                   	 System.err.println("redeis数据库token不存在");
	                   		boolean dbtokenExist = new UserLoginService().getUserByToken(token);
	                   		if(!dbtokenExist) {
	                   		  msg.setMsg(Consists.Error_Msg__TokenTimeout);
	                   		  msg.setCode(Consists.DATA_Code_OK__NODATA);
	                   		   System.err.println("msql数据库token不存在");
	           	        	  list.add(msg);
	           	        	  ResponseUtil.sendScript((HttpServletResponse)response, JSON.toJSONString(list));
	           	        	  return;
	                   		}
	                   	}
	                  	//签名验证
	          			Map<String, String> params=new HashMap<>();
	          			params.put("time", time);
	          			params.put("token", token);
	          			if(!Sign.createSign(params, true).equals(sign)) {
	          				msg.setMsg(Consists.Error_Msg__TokenTimeout);
	          				msg.setCode(Consists.DATA_Code_OK__NODATA);
	          				 System.err.println("签名不统一");
	          	        	list.add(msg);
	          	        	ResponseUtil.sendScript((HttpServletResponse)response, JSON.toJSONString(list));
	          	        	return;
	          			}
	          			chain.doFilter(request, response);
	             	}
	        }
       
		
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
		
		 chain_do_str = fConfig.getInitParameter("chain_do");     
	        if (null!=chain_do_str && chain_do_str.length()!=0) { // 不需要过滤的方法
	            chain_do_arr = chain_do_str.split(String.valueOf(';'));     
	        }    
	}

}
